﻿using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using wwl.Domain.Entities.Rbac;

namespace wwl.DataAccess.Mappings.Rbac
{
  /// <summary>
  /// 角色实体映射配置类（EF Core 数据映射）
  /// 负责配置角色领域实体与数据库表 rbac_role 之间的映射关系和业务约束
  /// 设计目标：实现角色数据的规范存储，支撑灵活的权限分配和访问控制需求
  /// </summary>
  public class RoleMap : IEntityTypeConfiguration<Role>
  {
    /// <summary>
    /// 配置角色实体的数据库映射细节
    /// </summary>
    /// <param name="builder">实体类型构建器，提供流畅API配置实体到数据库的映射规则</param>
    /// <remarks>
    /// 1. 业务约束：通过数据库约束保障角色数据的规范性和一致性
    /// 2. 性能优化：针对角色查询场景设计合适的索引策略
    /// 3. 扩展考虑：预留字段长度支持未来业务扩展需求
    /// 4. 多租户支持：完善的租户隔离机制设计
    /// </remarks>
    public void Configure(EntityTypeBuilder<Role> builder)
    {
      // 指定表名：明确映射到 rbac_role 表，保持RBAC模块命名的一致性
      builder.ToTable("rbac_role");

      // 配置主键：字符串类型主键，支持灵活的ID生成策略
      builder.HasKey(x => x.Id);

      #region 属性映射配置
      builder.Property(x => x.Id)
          .HasColumnName("id")
          .HasMaxLength(64)
          .IsRequired();

      // 角色编码映射：唯一索引保障角色编码全局唯一，业务标识的核心字段
      builder.Property(x => x.RoleCode)
          .HasColumnName("role_code")
          .HasMaxLength(64)
          .IsRequired();

      // 角色名称映射：128字符长度支持详细的角色描述，业务展示的重要字段
      builder.Property(x => x.RoleName)
          .HasColumnName("role_name")
          .HasMaxLength(128)
          .IsRequired();

      // 角色类型映射：字符串存储提升可读性，检查约束确保类型值的合法性
      builder.Property(x => x.RoleType)
          .HasColumnName("role_type")
          .HasConversion<string>()
          .HasMaxLength(20)
          .IsRequired();

      // 租户标识映射：支持多租户角色隔离，可空设计适应系统级角色场景
      builder.Property(x => x.TenantId)
          .HasColumnName("tenant_id")
          .HasMaxLength(64);

      // 基础实体属性映射
      builder.Property(x => x.CreatedTime)
          .HasColumnName("created_time")
          .IsRequired();

      builder.Property(x => x.UpdatedTime)
          .HasColumnName("updated_time")
          .IsRequired();

      builder.Property(x => x.CreatedBy)
          .HasColumnName("created_by")
          .HasMaxLength(64)
          .IsRequired();

      builder.Property(x => x.Remarks)
          .HasColumnName("remarks")
          .HasColumnType("text");

      builder.Property(x => x.IsDeleted)
          .HasColumnName("is_deleted")
          .HasDefaultValue(false);
      #endregion

      #region 索引配置
      // 角色编码唯一索引：保障角色标识的唯一性，提升角色编码查询性能
      builder.HasIndex(x => x.RoleCode)
          .IsUnique()
          .HasDatabaseName("ix_rbac_role_role_code");

      // 租户索引：支持按租户查询角色列表，优化多租户数据隔离场景
      builder.HasIndex(x => x.TenantId)
          .HasDatabaseName("ix_rbac_role_tenant_id");
      #endregion

      #region 约束配置
      // 角色类型检查约束：数据库层面保障角色类型值的合法性
      builder.ToTable(tableBuilder =>
      {
        tableBuilder.HasCheckConstraint(
            "ck_rbac_role_type",
            "role_type IN ('SYSTEM', 'BUSINESS')"
        );
      });
      #endregion
    }
  }
}